home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / bbs_util / bsrc_260.zip / SRC.ZIP / VERSION7.C < prev    next >
C/C++ Source or Header  |  1996-03-23  |  15KB  |  482 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*              (C) Copyright 1987-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*                  This module was adapted by Bill Andrus                  */
  13. /*                With the usual kibitzing by Vince Perriello               */
  14. /*              BinkleyTerm Version7 Nodelist processing module             */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. /* This table has been modified to minimize searches */
  49. char unwrk[] = " EANROSTILCHBDMUGPKYWFVJXZQ-'0123456789";
  50.  
  51. static long LOCALFUNC btree (char *, void *, int (LOCALFUNC *) (void *, void *, int));
  52. static int LOCALFUNC get_ver7_info (unsigned long, ADDRP);
  53. static struct _ndx far *LOCALFUNC get7node (HFILE, unsigned long, struct _ndx far *);
  54. static void LOCALFUNC unpk (char *instr, char *outp, int many);
  55. static int LOCALFUNC addr_compare (void *, void *, int);
  56. static int LOCALFUNC name_compare (void *, void *, int);
  57. extern int get_nodelist_name (ADDRP);
  58.  
  59. extern char *nodelist_base;
  60. extern char *nodelist_name;
  61. static char index_filename[260];
  62.  
  63. static int namelen;
  64.  
  65. static struct _ndx far *nodeidx = NULL;            /* index file             */
  66. static struct _ndx far *noderef = NULL;            /* index file             */
  67.  
  68. int 
  69. ver7find (ADDRP opus_addr, int have_boss_data)
  70. {
  71.     long record;
  72.     ADDR found_addr;
  73.  
  74.     have_boss_data = have_boss_data;
  75.  
  76.     newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  77.  
  78.     if (!get_nodelist_name (opus_addr))
  79.         return 0;
  80.     index_filename[0] = '\0';                    /* "null-terminated string*/
  81.     (void) strcpy (index_filename, net_info);    /* take nodelist path     */
  82.     (void) strcat (index_filename, nodelist_base); /* add in the file name*/
  83.     (void) strcat (index_filename, ".NDX");        /* add in the file ext    */
  84.  
  85.     record = btree (index_filename, (void *) opus_addr, addr_compare);
  86.  
  87.     if (record == -1)
  88.         return (0);
  89.     else
  90.         return (get_ver7_info ((unsigned long) record, &found_addr));
  91. }
  92.  
  93. static int LOCALFUNC 
  94. addr_compare (void *key, void *desired, int len)
  95. {
  96.     int k;
  97.  
  98.     k = ((ADDRP) key)->Zone - ((ADDRP) desired)->Zone;
  99.     if (k)
  100.         return (k);
  101.  
  102.     k = ((ADDRP) key)->Net - ((ADDRP) desired)->Net;
  103.     if (k)
  104.         return (k);
  105.  
  106.     k = ((ADDRP) key)->Node - ((ADDRP) desired)->Node;
  107.     if (k)
  108.         return (k);
  109. /*
  110.  * Node matches.
  111.  *
  112.  * The rule for points:
  113.  *  1) If len == 6, treat key value for Point as Zero.
  114.  *  2) Return comparison of key Point and desired Point.
  115.  */
  116.     if (len == 6)
  117.         ((ADDRP) key)->Point = 0;
  118.  
  119.     return ((ADDRP) key)->Point - ((ADDRP) desired)->Point;
  120. }
  121.  
  122. void 
  123. opususer (char *name, ADDRP faddr)
  124. {
  125.     char last_name_first[80];
  126.     char midname[80];
  127.     char *c, *p, *m;
  128.     long record;
  129.  
  130.     faddr->Zone = faddr->Net = faddr->Node = faddr->Point = (unsigned short) -1;
  131.     faddr->Domain = NULL;
  132.  
  133.     c = midname;                                /* Start of temp name buff   */
  134.     p = name;                                    /* Point to start of name    */
  135.     m = NULL;                                    /* Init pointer to space     */
  136.  
  137.     *c = *p++;
  138.     while (*c)                                    /* Go entire length of name  */
  139.     {
  140.         if (*c == ' ')                            /* Look for space            */
  141.             m = c;                                /* Save location             */
  142.         c++;
  143.         *c = *p++;
  144.     }
  145.  
  146.     if (m != NULL)                                /* If we have a pointer,     */
  147.     {
  148.         *m++ = '\0';                            /* Terminate the first half  */
  149.         (void) strcpy (last_name_first, m);        /* Now copy the last name    */
  150.         (void) strcat (last_name_first, ", ");    /* Insert a comma and space  */
  151.         (void) strcat (last_name_first, midname); /* Finally copy first half */
  152.     }
  153.     else
  154.         (void) strcpy (last_name_first, midname); /* Use whole name otherwise*/
  155.  
  156.     (void) fancy_str (last_name_first);            /* Get caps in where needed  */
  157.     namelen = (int) strlen (last_name_first);    /* Calc length now           */
  158.  
  159.     index_filename[0] = '\0';                    /* "null-terminated string"  */
  160.  
  161.     if (nodelist_base == NULL)
  162.         get_nodelist_name (&my_addr);            /* fill in nodelist.base     */
  163.     (void) strcpy (index_filename, net_info);    /* take nodelist path        */
  164.     (void) strcat (index_filename, "SYSOP.NDX"); /* add in the file name     */
  165.  
  166.     record = btree (index_filename, (void *) last_name_first, name_compare);
  167.  
  168.     if (record == -1)
  169.         return;
  170.  
  171.     (void) get_ver7_info ((unsigned long) record, faddr);
  172. }
  173.  
  174. static int LOCALFUNC 
  175. name_compare (void *key, void *desired, int len)
  176. {
  177.     return (strnicmp ((char *) key, (char *) desired, (unsigned int) min (namelen, len)));
  178. }
  179.  
  180. /*
  181.  * General V7 nodelist engine. Used by both the by-node and by-sysop
  182.  * lookups.
  183.  *
  184.  * Thanks to Phil Becker for showing me how nice it looks in assembler.
  185.  * It helped me see how nice it could be in C.
  186.  *
  187.  * (I know, Phil, it's still nicer in assembler!)
  188.  *
  189.  */
  190.  
  191. static long LOCALFUNC 
  192. btree (char *filename, void *desired, int (LOCALFUNC * compare) (void *key, void *desired, int len))
  193. {
  194.     int j, k, l;
  195.     struct _IndxRef far *ip = NULL;
  196.     struct _LeafRef far *lp = NULL;
  197.     char aline[160];
  198.     char far *tp;
  199.     char *np;
  200.  
  201.     long record, foundrec = -1L;
  202.     int count;
  203.  
  204.     HFILE stream;
  205.  
  206.     if ((stream = (HFILE) share_open (filename, O_RDONLY | O_BINARY, DENY_WRITE)) == (HFILE) - 1)
  207.         return (-1L);            /* no file, no work to do */
  208.  
  209.     if (node_index == NULL)
  210.         node_index = _fmalloc (sizeof (struct _ndx));
  211.  
  212.     if (nodeidx == NULL)
  213.         nodeidx = _fmalloc (sizeof (struct _ndx));
  214.  
  215.     if (noderef == NULL)
  216.         noderef = _fmalloc (sizeof (struct _ndx));
  217.  
  218.     if (node_index == NULL)
  219.     {
  220.         status_line (msgtxt[M_NODELIST_MEM]);
  221.         (void) close (stream);
  222.         return (-1L);
  223.     }
  224.  
  225.     /* Get CtlRec */
  226.     if (get7node (stream, 0L, noderef) != noderef)
  227.     {
  228.         close (stream);
  229.         return (-1L);
  230.     }
  231.  
  232.     /* The guts of the matter -- walk from CtlRec to Leaf */
  233.  
  234.     record = noderef->ndx.CtlBlk.CtlRoot;
  235.  
  236. /*
  237.  * Read the first Index node.
  238.  */
  239.     if (get7node (stream, (unsigned long) (record * noderef->ndx.CtlBlk.CtlBlkSize), nodeidx) != nodeidx)
  240.     {
  241.         close (stream);
  242.         return (-1L);
  243.     }
  244. /*
  245.  * Follow the node tree until we either match a key right in the index
  246.  * node, or locate the leaf node which must contain the entry.
  247.  */
  248.     while (nodeidx->ndx.INodeBlk.IndxFirst != -1)
  249.     {
  250.         if ((count = nodeidx->ndx.INodeBlk.IndxCnt) == 0)
  251.         {
  252.             j = 0;
  253.         }
  254.         else
  255.             for (j = 0; j < count; j++)    /* check 20 or less */
  256.             {
  257.                 ip = &(nodeidx->ndx.INodeBlk.IndxRef[j]);
  258.                 tp = (char far *) nodeidx + ip->IndxOfs;
  259.  
  260.                 k = l = ip->IndxLen;
  261.  
  262.                 for (np = aline; k > 0; k--)
  263.                     *np++ = *tp++;
  264.  
  265.                 k = (*compare) ((void *) aline, desired, l);
  266.  
  267.                 if (k > 0)
  268.                     break;
  269.  
  270.                 if (k == 0)
  271.                 {
  272.  
  273. /* Key matches in the index node. Since we're just doing lookup, we
  274.  * can assume its pointer is valid. If we were doing updates, that
  275.  * assumption would not work, because leaf nodes update first. So in
  276.  * an update environment, the entire code segment relating to k == 0
  277.  * should not execute, and we should walk the tree all the way down.
  278.  */
  279.                     close (stream);
  280.                     return (nodeidx->ndx.INodeBlk.IndxRef[j].IndxData);
  281.                 }
  282.             }
  283.  
  284.         if (j == 0)
  285.             record = nodeidx->ndx.INodeBlk.IndxFirst;
  286.         else
  287.             record = (nodeidx->ndx.INodeBlk.IndxRef[--j]).IndxPtr;
  288.  
  289.         if (get7node (stream, (unsigned long) (record * noderef->ndx.CtlBlk.CtlBlkSize), nodeidx) != nodeidx)
  290.         {
  291.             close (stream);
  292.             return (-1L);
  293.         }
  294.  
  295.     }
  296. /*
  297.  * We can only get here if we've found the leafnode which must
  298.  * contain our entry.
  299.  *
  300.  * Find our guy here or die trying.
  301.  */
  302.     if ((count = nodeidx->ndx.LNodeBlk.IndxCnt) != 0)
  303.     {
  304.         /* Search for a higher key */
  305.  
  306.         for (j = 0; j < count; j++)    /* check 30 or less */
  307.         {
  308.             lp = &(nodeidx->ndx.LNodeBlk.LeafRef[j]);
  309.             tp = (char far *) nodeidx + lp->KeyOfs;
  310.  
  311.             k = l = lp->KeyLen;
  312.  
  313.             for (np = aline; k > 0; k--)
  314.                 *np++ = *tp++;
  315.  
  316.             k = (*compare) ((void *) aline, desired, l);
  317.  
  318.             if (k > 0)
  319.                 break;
  320.             if (k == 0)
  321.             {
  322.                 foundrec = (nodeidx->ndx.LNodeBlk.LeafRef[j]).KeyVal;
  323.                 break;
  324.             }
  325.         }
  326.     }
  327.  
  328.     (void) close (stream);
  329.     return (foundrec);
  330. }
  331.  
  332. static int LOCALFUNC 
  333. get_ver7_info (unsigned long pos, ADDRP faddr)
  334. {
  335.     struct _vers7 vers7;
  336.     char my_phone[40];
  337.     char my_pwd[9];
  338.     char aline[160];
  339.     char aline2[160];
  340.     char *fst;
  341.     char temp[80];                                /* we build filenames here*/
  342.     FILE *stream;
  343.  
  344.     (void) strcpy (temp, net_info);                /* take nodelist path */
  345.     (void) strcat (temp, nodelist_base);        /* add in the filename*/
  346.     (void) strcat (temp, ".DAT");                /* then the extension */
  347.     if ((stream = share_fopen (temp, read_binary, DENY_WRITE)) == NULL)
  348.     {
  349.         status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
  350.         return (0);
  351.     }
  352.  
  353.     if (fseek (stream, (long int) pos, SEEK_SET)) /* point at record  */
  354.     {
  355.         status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
  356.         (void) fclose (stream);
  357.         return (0);
  358.     }
  359.  
  360.     if (!fread ((char *) &vers7, sizeof (struct _vers7), 1, stream))
  361.     {
  362.         status_line (msgtxt[M_NODELIST_REC_ERR], temp);
  363.         (void) fclose (stream);
  364.         return (0);
  365.     }
  366.  
  367.     (void) memset (my_phone, '\0', 40);
  368.     (void) fread (my_phone, vers7.Phone_len, 1, stream);
  369.  
  370.     (void) memset (my_pwd, '\0', 9);
  371.     (void) fread (my_pwd, vers7.Password_len, 1, stream);
  372.  
  373.     (void) memset (aline, '\0', 160);
  374.     (void) memset (aline2, '\0', 160);
  375.     if (!fread (aline2, vers7.pack_len, 1, stream))
  376.     {
  377.         status_line (msgtxt[M_NODELIST_REC_ERR], temp);
  378.         (void) fclose (stream);
  379.         return (0);
  380.     }
  381.  
  382.     (void) fclose (stream);
  383.  
  384.     unpk (aline2, aline, vers7.pack_len);
  385.  
  386.     (void) memset (&newnodedes, 0, sizeof (struct _newnode));
  387.  
  388.     newnodedes.NetNumber = vers7.Net;
  389.     newnodedes.NodeNumber = vers7.Node;
  390.     newnodedes.Cost = newnodedes.RealCost = vers7.CallCost;
  391.     (void) memcpy (newnodedes.SystemName, aline, min (33, vers7.Bname_len));
  392.     newnodedes.SystemName[min (33, vers7.Bname_len)] = '\0';
  393.     (void) fancy_str (newnodedes.SystemName);
  394.  
  395.     fst = &aline[0] + vers7.Bname_len + vers7.Sname_len;
  396.     (void) memcpy (newnodedes.PhoneNumber, my_phone, min (39, vers7.Phone_len));
  397.     newnodedes.PhoneNumber[min (39, vers7.Phone_len)] = '\0';
  398.     (void) memcpy (newnodedes.MiscInfo, fst, min (29, vers7.Cname_len));
  399.     newnodedes.MiscInfo[min (29, vers7.Cname_len)] = '\0';
  400.     (void) fancy_str (newnodedes.MiscInfo);
  401.  
  402.     (void) memcpy (newnodedes.Password, my_pwd, min (8, vers7.Password_len));
  403.     newnodedes.HubNode = vers7.HubNode;
  404.     newnodedes.BaudRate = vers7.BaudRate;
  405.     newnodedes.ModemType = vers7.ModemType;
  406.     newnodedes.NodeFlags = vers7.NodeFlags;
  407.  
  408.     found_zone = faddr->Zone = vers7.Zone;
  409.     found_net = faddr->Net = vers7.Net;
  410.     faddr->Node = vers7.Node;
  411.     if (vers7.NodeFlags & B_point)
  412.         faddr->Point = vers7.HubNode;
  413.     else
  414.         faddr->Point = 0;
  415.     faddr->Domain = NULL;
  416.  
  417.     return (1);
  418. }
  419.  
  420. static struct _ndx far *LOCALFUNC 
  421. get7node (HFILE stream, unsigned long pos, struct _ndx far * ndx)
  422. {
  423.     unsigned long got;
  424.  
  425.     (void) lseek (stream, (long) pos, SEEK_SET);
  426.  
  427.     /* Note, we do not use "got". Some platforms want it to be a long
  428.        and some want it to be a int. We don't care, so we make it a
  429.        long (see above) so there's enough room, then use a void * so
  430.        the compiler won't complain about an argument we don't even want */
  431.  
  432.     if (_dos_read (stream, ndx, (unsigned int) sizeof (struct _ndx), (void *)&got) != 0)
  433.     {
  434.         status_line (msgtxt[M_NODELIST_READ_ERR]);
  435.         (void) close (stream);
  436.         return (NULL);
  437.     }
  438.     return (ndx);
  439. }
  440.  
  441. /* ====================================================================
  442.  * unpack a dense version of a symbol (base 40 polynomial)
  443.  * ====================================================================
  444.  */
  445.  
  446. static void LOCALFUNC 
  447. unpk (char *instr, char *outp, int count)
  448. {
  449.     struct chars
  450.     {
  451.         unsigned char c1;
  452.         unsigned char c2;
  453.     };
  454.  
  455.     union
  456.     {
  457.         unsigned short w1;
  458.         struct chars d;
  459.     } u;
  460.  
  461.     register short i, j;        /* MB int */
  462.     char obuf[4];
  463.  
  464.     outp[0] = '\0';
  465.  
  466.     while (count)
  467.     {
  468.         u.d.c1 = *instr++;
  469.         u.d.c2 = *instr++;
  470.         count -= 2;
  471.         for (j = 2; j >= 0; j--)
  472.         {
  473.             i = u.w1 % 40;
  474.             u.w1 /= 40;
  475.             obuf[j] = unwrk[i];
  476.         }
  477.         obuf[3] = '\0';
  478.         (void) strcat (outp, obuf);
  479.     }
  480. }
  481.  
  482.